package com.cg.asm.core.service.menu.impl;

import com.cg.asm.core.dao.menu.MenuMapper;
import com.cg.asm.core.domain.vo.menu.MenuUserLoginVO;
import com.cg.asm.core.service.menu.IMenuService;
import com.github.pagehelper.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MenuService implements IMenuService {

    private MenuMapper menuMapper;

    public MenuService(MenuMapper menuMapper) {
        this.menuMapper = menuMapper;
    }

    @Override
    public List<MenuUserLoginVO> getUserMenuInfo(String userId,String userGroupId,String platformTypeCode) {
        if(StringUtil.isEmpty(platformTypeCode)){
            /**
             * platformTypeCode：
             *    1.平台类型编码是必须项
             *    2.未传值则返回空数组
             * 备注：功能清单第一级则为平台类型
             */
           return new ArrayList<>();
        }
        //根据用户Id获取用户所有功能清单
        List<MenuUserLoginVO> menuUserLoginList = menuMapper.getUserMenuInfo(userId);
        if(StringUtils.isNotEmpty(userGroupId)){
            List<MenuUserLoginVO> menuUserGroupList = menuMapper.getUserGroupMenuInfo(userGroupId);
            if(null != menuUserGroupList && menuUserGroupList.size() != 0){
                menuUserLoginList.addAll(menuUserGroupList);
            }
        }
        //获取所有分组类功能清单
        List<MenuUserLoginVO> menuGroups = menuMapper.getMenuGroup();
        //存储用户功能清单:包含功能类、分组类
        Map<String, MenuUserLoginVO> userMenuByAll = new HashMap<>();

        //根据用户功能清单，查找所有父级功能清单信息
        //并存储到userMenuByAll数据集中
        for (MenuUserLoginVO menuUserLogin : menuUserLoginList) {
            if (null != menuUserLogin) {
                userMenuByAll.put(menuUserLogin.getSelfLevelCode(), menuUserLogin);
                String parentCode = menuUserLogin.getParentLevelCode();
                if (StringUtil.isNotEmpty(parentCode)) {
                    this.findParentMenu(userMenuByAll, menuGroups, parentCode);
                }
            }
        }

        //存储功能清单树信息
        List<MenuUserLoginVO> userMenuTree = new ArrayList<>();

        //根据userMenuByAll数据集构建功能清单树
        //并存储到userMenuTree数据集中
        for (String levelCode : userMenuByAll.keySet()) {
            MenuUserLoginVO menuUserLogin = userMenuByAll.get(levelCode);
            if (null != menuUserLogin) {
                if (StringUtil.isEmpty(menuUserLogin.getParentLevelCode())) {
                    this.findChildrenMenu(menuUserLogin, userMenuByAll);
                    userMenuTree.add(menuUserLogin);
                }
            }
        }

        if (userMenuTree.size() != 0) {
            // 过滤平台节点
            userMenuTree = userMenuTree.stream().filter(i -> i.getFunListCode().equals(platformTypeCode))
                                       .map(MenuUserLoginVO::getChildren)
                                       .findAny()
                                       .orElse(new ArrayList<>());
            // 根据排序标识进行排序
            this.listSort(userMenuTree);
        }

        return userMenuTree;
    }

    /**
     * 根据父级层级编码查找所有父级信息
     *
     * @param userMenuByAll 存储根据父级编码查询出的父级信息
     * @param menuGroups    所有分组功能清单
     * @param parentCode    父级编码
     */
    private void findParentMenu(Map<String, MenuUserLoginVO> userMenuByAll, List<MenuUserLoginVO> menuGroups, String parentCode) {
        for (MenuUserLoginVO menuGroup : menuGroups) {
            if (null != menuGroup) {
                String selfLevelCode = menuGroup.getSelfLevelCode();
                if (parentCode.equals(selfLevelCode)) {
                    if (!userMenuByAll.containsKey(selfLevelCode)) {
                        userMenuByAll.put(selfLevelCode, menuGroup);
                        String parentLevel = menuGroup.getParentLevelCode();
                        if (StringUtil.isNotEmpty(parentLevel)) {
                            this.findParentMenu(userMenuByAll, menuGroups, parentLevel);
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据顶级菜单构建所有子集
     *
     * @param menu
     * @param userMenuByAll
     */
    private void findChildrenMenu(MenuUserLoginVO menu, Map<String, MenuUserLoginVO> userMenuByAll) {
        List<MenuUserLoginVO> menuUserLoginList = new ArrayList<>();
        for (String levelCode : userMenuByAll.keySet()) {
            MenuUserLoginVO childrenMenu = userMenuByAll.get(levelCode);
            if (null != childrenMenu) {
                if (menu.getSelfLevelCode().equals(childrenMenu.getParentLevelCode())) {
                    menuUserLoginList.add(childrenMenu);
                    this.findChildrenMenu(childrenMenu, userMenuByAll);
                }
            }
        }
        if (menuUserLoginList.size() != 0) {
            if (menuUserLoginList.size() != 0) {
                this.listSort(menuUserLoginList);
            }
            menu.setChildren(menuUserLoginList);
        }
    }

    /**
     * 集合排序
     *
     * @param sortArray
     */
    private void listSort(List<MenuUserLoginVO> sortArray) {
        Collections.sort(sortArray, Comparator.comparing(MenuUserLoginVO::getFunListOrder));
    }
}
